﻿#region "Author section"

//<remarks>
//================================================================================
// Name: Variation Definition
// Pupose: To Create Heirarchy and to Update Variation Setting and Properties List
// Construction Date: 10-Aug-2010
// Author:Kshitij Bishnoi
//================================================================================
//</remarks>

# endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Text;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Linq;

namespace SiteVariation
{
    /// <summary>
    /// Contains the methods for site Variation Defination 
    /// </summary>
    public static class VariationDefinition
    {
        #region "Methods"

        /// <summary>
        /// This method defines how to create Site Variation 
        /// </summary>
        /// <param name="web">Curent Web address</param>
        /// <param name="featureProperties">Gives collection of properties defined in feature.xml</param>
        public static void CreateVariation(SPWeb web, SPFeaturePropertyCollection featureProperties, SPWebApplication parentWeb)
        {

            //Updating Site Variation Settings
            UpdateVariationSettings(web, featureProperties);

            //Adding Site Variation Labels
            AddingVariationLabels(web, featureProperties);

            //Creating Site hierarchies for English and Spanish Language
            CreateSiteHierarchies(web, parentWeb);           

        }


        /// <summary>
        /// Method used for adding the Variation labels to the specified web.
        /// </summary>
        /// <param name="web">Current Web</param>
        /// <param name="featureProperties">Give the collection Properties defined in the feature.xml file</param>
        private static void AddingVariationLabels(SPWeb web, SPFeaturePropertyCollection featureProperties)
        {
            try
            {
                //Getting variation label List Id
                string varListId = web.AllProperties["_VarLabelsListId"].ToString();
                SPList VarList = web.Lists[new Guid(varListId)];

                // Read labels from feature.xml
                VariationLabel[] variationLabels = ReadVariationLabelsFromProperties(featureProperties);

                if (variationLabels != null && variationLabels.Length > 0)
                {                   
                    foreach (VariationLabel label in variationLabels)
                    {
                        // Adding the labels to the sharepoint hidden Variation Label List.
                        SPListItem varListItem = VarList.Items.Add();
                        varListItem[VariationConstants.VariationLabelProperties.TITLE] = label.Label;
                        varListItem[VariationConstants.VariationLabelProperties.DESCRIPTION] = label.Description;
                        varListItem[VariationConstants.VariationLabelProperties.FLAG_CONTROL_DISPLAY_NAME] = label.DisplayName;
                        varListItem[VariationConstants.VariationLabelProperties.HIERARCHY_CREATION_MODE] = "Publishing Sites and All Pages";
                        varListItem[VariationConstants.VariationLabelProperties.IS_SOURCE] = label.IsSource;
                        varListItem[VariationConstants.VariationLabelProperties.LANGUAGE] = label.Language;
                        varListItem[VariationConstants.VariationLabelProperties.HIERARCHY_IS_CREATED] = false;
                        varListItem[VariationConstants.VariationLabelProperties.LOCALE] = label.Locale;

                        varListItem.Update();
                    }
                    
                }
                else
                {
                    throw new Exception("No Variation Labels to add.");
                }
            }
            catch (NullReferenceException ex)
            {
               
            }
            catch (Exception ex)
            {
                
            }
        }

        /// <summary>
        /// Method used for Updating the default Variation settings of the specified web.
        /// </summary>
        /// <param name="web">Current Web</param>
        /// <param name="featureProperties">Give the collection Properties defined in the feature.xml file</param>
        private static void UpdateVariationSettings(SPWeb web, SPFeaturePropertyCollection featureProperties)
        {
            try
            {                

                // Get handle to the Variation Relationship Settings List
                string varRelationshipsListId = web.AllProperties["_VarRelationshipsListId"].ToString();
                SPList variationSettingsList = web.Lists[new Guid(varRelationshipsListId)];

                //Getting the variation settings defined for Site.
                VariationSettings variationSettings = ReadVariationSettingsFromProperties(featureProperties);

                //Settings the Variation at root web.
                SPListItem variationroot = variationSettingsList.Items[0];
                variationroot["ObjectID"] = string.Format(CultureInfo.InvariantCulture, "{0}/, " + variationSettings.ObjectID + "", web.Site.Url);
                variationroot.Update();

                Hashtable properties = variationSettingsList.RootFolder.Properties;
                properties[VariationConstants.VariationSettingsProperties.SOURCE_VARROOT_WEBTEMPLATE_PROPERTY_NAME] = variationSettings.SourceVarRootWebTemplatePropertyName.ToString();
                properties[VariationConstants.VariationSettingsProperties.ENABLE_AUTOSPAWN_PROPERTY_NAME] = variationSettings.EnableAutoSpawnPropertyName.ToString();
                properties[VariationConstants.VariationSettingsProperties.AUTO_SPAWN_STOP_AFTER_DELETE_PROPERTY_NAME] = variationSettings.AutoSpawnStopAfterDeletePropertyName.ToString();
                properties[VariationConstants.VariationSettingsProperties.UPDATE_WEBPARTS_PROPERTY_NAME] = variationSettings.UpdateWebPartsPropertyName.ToString();
                properties[VariationConstants.VariationSettingsProperties.COPY_RESOURCES_PROPERTY_NAME] = variationSettings.CopyResourcesPropertyName.ToString();
                properties[VariationConstants.VariationSettingsProperties.SEND_NOTIFICATION_EMAIL_PROPERTY_NAME] = variationSettings.SendNotificationEmailPropertyName.ToString();
                variationSettingsList.RootFolder.Update();
            }
            catch (NullReferenceException ex)
            {
                
            }
            catch (Exception ex)
            {
                
            }         
        }

        /// <summary>
        /// This method defines how to read the variation Settings from feature.xml
        /// </summary>
        /// <param name="properties">Gives collection of properties defined in feature.xml</param>
        /// <returns>Object which is used to set the variation settings</returns>
        private static VariationSettings ReadVariationSettingsFromProperties(SPFeaturePropertyCollection properties)
        {
            VariationSettings variationSettings = new VariationSettings();

            SPFeatureProperty propHomeUrl = properties[VariationConstants.FeatureProperties.VARIATION_HOME_URL];
            if (propHomeUrl != null)
            {
                if (!string.IsNullOrEmpty(propHomeUrl.Value))
                {
                    string tmp = propHomeUrl.Value;
                    if (!tmp.StartsWith("/"))
                    {
                        tmp = string.Concat('/', tmp);
                    }
                    variationSettings.ObjectID = tmp;
                }
            }
            SPFeatureProperty propTemplateName = properties[VariationConstants.FeatureProperties.SOURCE_VARIATION_TEMPLATE_NAME];
            if (propTemplateName != null)
            {
                if (!string.IsNullOrEmpty(propTemplateName.Value))
                {
                    variationSettings.SourceVarRootWebTemplatePropertyName = propTemplateName.Value;
                }
            }
            SPFeatureProperty propCreateSitePage = properties[VariationConstants.FeatureProperties.AUTOMATIC_CREATION_OF_SITES_PAGES];
            if (propCreateSitePage != null)
            {
                bool tmp;
                bool.TryParse(propCreateSitePage.Value, out tmp);
                variationSettings.EnableAutoSpawnPropertyName = tmp;
            }
            SPFeatureProperty propTargetPage = properties[VariationConstants.FeatureProperties.RECREATE_OR_DELETED_TARGET_PAGE];
            if (propTargetPage != null)
            {
                bool tmp = bool.Parse(propTargetPage.Value);
                variationSettings.AutoSpawnStopAfterDeletePropertyName = !tmp;
            }
            SPFeatureProperty propUpdateTargetPage = properties[VariationConstants.FeatureProperties.UPDATE_TARGET_PAGE_WEBPARTS];
            if (propUpdateTargetPage != null)
            {
                bool tmp = bool.Parse(propUpdateTargetPage.Value);
                variationSettings.UpdateWebPartsPropertyName = tmp;
            }
            SPFeatureProperty propSendMail = properties[VariationConstants.FeatureProperties.SEND_MAIL_NOTIFICATION];
            if (propSendMail != null)
            {
                bool tmp = bool.Parse(propSendMail.Value);
                variationSettings.SendNotificationEmailPropertyName = tmp;
            }
            SPFeatureProperty propCopyResources = properties[VariationConstants.FeatureProperties.COPY_RESOURCES];
            if (propCopyResources != null)
            {
                bool tmp = bool.Parse(propCopyResources.Value);
                variationSettings.CopyResourcesPropertyName = tmp;
            }

            return variationSettings;
        }

        /// <summary>
        /// This method defines how to read the variation Lables properties from feature.xml
        /// </summary>
        /// <param name="featureProperties">Gives collection of properties defined in feature.xml</param>
        /// <returns>object array to set the variation label for both english and Spanish</returns>
        private static VariationLabel[] ReadVariationLabelsFromProperties(SPFeaturePropertyCollection featureProperties)
        {
            List<VariationLabel> varList = new List<VariationLabel>();

            SPFeatureProperty prop = featureProperties[string.Format(VariationConstants.FeatureProperties.LABEL, "1")];
            if (prop != null)
            {
                int labelCount = 1;
                bool continueLoop = true;
                while (continueLoop)
                {
                    continueLoop = false;

                    string labelKey = string.Format(VariationConstants.FeatureProperties.LABEL, labelCount);
                    string descriptionKey = string.Format(VariationConstants.FeatureProperties.LABEL_DESCRIPTION, labelCount);
                    string displayNameKey = string.Format(VariationConstants.FeatureProperties.LABEL_DISPLAY_NAME, labelCount);
                    string isSourceKey = string.Format(VariationConstants.FeatureProperties.LABEL_IS_SOURCE, labelCount);
                    string languageKey = string.Format(VariationConstants.FeatureProperties.LABEL_LANGUAGE, labelCount);
                    string localeKey = string.Format(VariationConstants.FeatureProperties.LABEL_LOCALE, labelCount);

                    VariationLabel varlabel = new VariationLabel();
                    SPFeatureProperty propLabel = featureProperties[labelKey];
                    if (propLabel != null)
                    {
                        varlabel.Label = propLabel.Value;

                        SPFeatureProperty propDescription = featureProperties[descriptionKey];
                        if (propDescription != null)
                            varlabel.Description = propDescription.Value;

                        SPFeatureProperty propDisplayName = featureProperties[displayNameKey];
                        if (propDisplayName != null)
                            varlabel.DisplayName = propDisplayName.Value;

                        SPFeatureProperty propIsSource = featureProperties[isSourceKey];
                        if (propIsSource != null)
                        {
                            bool tmp = bool.Parse(propIsSource.Value);
                            varlabel.IsSource = tmp;
                        }

                        SPFeatureProperty propLanguage = featureProperties[languageKey];
                        if (propLanguage != null)
                            varlabel.Language = propLanguage.Value;

                        SPFeatureProperty propLocale = featureProperties[localeKey];
                        if (propLocale != null)
                        {
                            int tmp = Int32.Parse(propLocale.Value);
                            varlabel.Locale = tmp;
                        }

                        if (!string.IsNullOrEmpty(varlabel.Label) && !string.IsNullOrEmpty(varlabel.DisplayName) && !string.IsNullOrEmpty(varlabel.Language) && varlabel.Locale > 0)
                        {
                            varList.Add(varlabel);
                            labelCount++;
                            continueLoop = true;
                        }
                    }
                }
            }

            return varList.ToArray();
        }        
       
        /// <summary>
        /// Creates the site hierarchies
        /// </summary>
        /// <param name="web">Current web</param>
        /// <param name="parentWeb">Current Web Apllication</param>
        private static void CreateSiteHierarchies(SPWeb web, SPWebApplication parentWeb)
        {           
            try
            {
                web.AllowUnsafeUpdates = true;
                SPSite mySite = web.Site;

                mySite.AddWorkItem(Guid.Empty, DateTime.Now.ToUniversalTime(),
                                    new Guid("e7496be8-22a8-45bf-843a-d1bd83aceb25"),
                                    mySite.RootWeb.ID, mySite.ID, 1, false, Guid.Empty,
                                    Guid.Empty, mySite.RootWeb.CurrentUser.ID, null, String.Empty,
                                    Guid.Empty, false); 

                SPJobDefinition createSiteHierarchyJob = (from SPJobDefinition job in
                                                              parentWeb.JobDefinitions
                                                          where job.Name == "VariationsCreateHierarchies"
                                                 select job).FirstOrDefault();
                createSiteHierarchyJob.RunNow();
                web.AllowUnsafeUpdates = false;                
            }
            catch (NullReferenceException ex)
            {
                
            }
            catch (Exception ex)
            {
                
            }            
        }
        
        #endregion
    }
}
